package chapter05

object Demo06_HighOrderFunction {
  def main(args: Array[String]): Unit = {

    def f(n : Int): Int = {
      println("调用一次F")
      n + 1
    }

    def fun() : Int ={
      println("fun调用")
      1
    }

    fun()
    fun

    val result: Int = f(123)
    println(result)

    //1、函数作为值进行传递
    val f1 = f  _  //f _ 表示f是一个整体  表示的是f 本身这个函数
    val f2: Int => Int = f

    //f1和f2都是有不同的引用
    println(f1)  //chapter05.Demo06_HighOrderFunction$$$Lambda$5/431687835@11531931
    println(f1(11))
    println(f2)  //chapter05.Demo06_HighOrderFunction$$$Lambda$6/1164175787@5e025e70
    println(f2(12))

    val f3 = fun
    val f4 = fun _
    val f5: () => Int = fun
    println(f3)  // 1 fun调用以后的返回值  如果把f3 的类型指定是函数特也就是函数了 ==>f5
    println(f4)  // chapter05.Demo06_HighOrderFunction$$$Lambda$7/2096171631@7e0babb1 本身是一个函数
    println(f5)  // chapter05.Demo06_HighOrderFunction$$$Lambda$8/2114694065@5ba23b66


    //2、函数做为参数进行传递
    // 定义一个二元运算函数
    def dualEval(op: (Int , Int) => Int , a: Int , b: Int): Int = {
      op(a , b)
    }

    def add(a: Int , b: Int): Int = {
      a + b
    }

    println(dualEval(add , 22 , 66))
    println(dualEval((a , b) => a + b , 44 , 55))
    println(dualEval(_ + _ , 77 , 88))


    //3、函数可以作为函数的返回值进行返回
    def f6(): Int=>Unit = {
      def f7(a: Int): Unit = {
        println("f6调用" + a)
      }
      f7  //将函数直接返回
    }

    println(f6()) // 得到一个引用（函数的对象）其实得到的是 f7 chapter05.Demo06_HighOrderFunction$$$Lambda$12/312116338@1b0375b3

    //真正调用f6 的话
    def f7 = f6()
    println(f7) //  chapter05.Demo06_HighOrderFunction$$$Lambda$12/312116338@1b0375b3
    println(f7(55))

    println(f6()(88))
  }

}
